הרצאה 14 - ניתוח לשיעורין
ניתוח לשיעורין:
- מתמקד בניתוח סיבוכיות הזמן במקרה הגרוע של סדרה של פעולות על מבנה נתונים, ולא של פעולה בודדת.
- הרעיון המרכזי: גם אם פעולה אחת מסוימת בסדרה היא מאוד יקרה (למשל ), ייתכן שעלות הפעולה הממוצעת לאורך כל הסדרה תהיה נמוכה משמעותית (למשל ).
- אם פעולות לוקחות זמן במקרה הגרוע, העלות לשיעורין של פעולה בודדת היא .
- אנלוגיה - נסיעה ברכב.
- ברוב הימים העלות היא אפס (לא מתדלקים), וביום אחד העלות גבוהה (תדלוק מלא).
- העלות לשיעורין היא חלוקת ההוצאה הכוללת במספר ימי הנסיעה כדי לקבל את ה"עלות הממוצעת" ליום.
שיטות לניתוח לשיעורין:
- שיטת הקיבוץ (Aggregate analysis method):
- מחשבים ישירות את העלות הכוללת של פעולות, כלומר חוסמים את הסכום (כאשר היא העלות האמיתית של הפעולה ה-). העלות לשיעורין היא הסכום הזה חלקי .
- שיטת החיוב (Accounting method):
- לכל פעולה נקבע "חיוב" (Charge / ) שיכול להיות שונה מהעלות האמיתית שלה ().
- מחייבים פעולות זולות בסכום גבוה מעלותן האמיתית. ההפרש נשמר כ"קרדיט" (או "דולרים") בתוך מבנה הנתונים.
- כאשר מגיעה פעולה יקרה, משתמשים ב"דולרים" שנצברו כדי לשלם עליה.
- כלל ברזל: אסור להיכנס למינוס (חוב). בכל שלב נתון , סך העלויות האמיתיות חייב להיות קטן או שווה לסך החיובים: .
דוגמאות לניתוחי לשיעורין:
- מחסנית עם פעולת Multipop:
- מחסנית התומכת ב-Push, Pop ו-Multipop(k) (המוציאה איברים או מרוקנת את המחסנית). העלות של Multipop יכולה להיות במקרה הגרוע.
- בשיטת הקיבוץ:
- מספר הפעמים שניתן להוציא איבר (Pop/Multipop) חסום על ידי מספר האיברים שהוכנסו (Push), שהוא לכל היותר .
- לכן, העלות הכוללת ל- פעולות היא , והעלות לשיעורין לפעולה היא .
- בשיטת החיוב:
- נחייב Push ב-2 דולר (1 לעלות ההכנסה, 1 נשמר על האיבר).
- נחייב Pop ו-Multipop ב-0 דולר.
- כששולפים איבר, משתמשים בדולר השמור עליו כדי לשלם את העלות. לכן העלות לשיעורין היא .
- מונה בינארי (Binary Counter):
- מונה המבצע פעולת Increment (הגדלה ב-1) על ידי הפיכת ביטים. עלות פעולה היא מספר הביטים שמשתנים. פעולה בודדת יכולה לעלות .
- בשיטת הקיבוץ:
- הביט הראשון מתהפך בכל פעולה, הביט השני ב- מהפעולות, הביט ה- ב- מהפעולות.
- סכום ההיפוכים ל- פעולות מתכנס ל-. לכן העלות לשיעורין היא .
- בשיטת החיוב:
- נחייב הפיכת ביט מ- ל- ב-2 דולר (1 משלם על ההיפוך הנוכחי, 1 נשמר על הביט שהפך ל-1).
- הפיכת ביט מ- ל- ממומנת על ידי הדולר שנשמר עליו (חיוב 0).
- מאחר שבכל Increment הופכים בדיוק אפס אחד לאחד, החיוב תמיד יהיה 2 דולר, ולכן העלות לשיעורין .
- טבלאות גיבוב דינאמיות (Dynamic Hash Tables):
- שמירה על "גורם עומס" (Load factor - ) בתחום כדי להבטיח זמן חיפוש צפוי של וצריכת זיכרון של .
- הכנסות בלבד:
- כאשר הטבלה מתמלאת (), מכפילים את גודלה ומעתיקים את האיברים (גיבוב מחדש).
- חיוב הכנסה ב-3 דולרים (1 להכנסה, 2 נשמרים בטבלה) מבטיח שכשנגיע לטבלה מלאה יהיה לנו מספיק "דולרים" כדי לממן את עלות ההעתקה לטבלה החדשה.
- הכנסות ומחיקות:
- אם נקטין טבלה מיד כשהיא מגיעה לחצי (), סדרה גרועה של (הכנסה, מחיקה, הכנסה...) תגרור גיבוב מחדש בכל שלב וסיבוכיות לפעולה.
- הפתרון הוא להקטין את הטבלה רק כאשר , מה שמאפשר לצבור מספיק חיובים מהמחיקות כדי לממן את העתקת האיברים בעת הכיווץ.
תובנות מהתרגול:
- ניתוח לשיעורין הוא דטרמניסטי - אין שימוש בהסתברות בניתוח העלות לשיעורין, בוחרים את הסדרה הרעה ביותר מבחינת זמן ריצה ומחלקים בכמות הפעולות.
- מחסנית עם גיבויים:
- מחסנית שבכל שלב ישנם לכל היותר K איברים במחסנית.
- המחסנית ממומשת על ידי מערך (זמני ההכנסה וההוצאה קבועים).
- לאחר כל K פעולות, מבוצע שכפול של כלל האיברים הנמצאים במכנסית לגיבוי.
- העלות לשיעורין: של פעולת ההכנסה וההוצאה ברצף של n > k היא טטא של 1.